package com.doeis.uwork.servce;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.doeis.minaserver.NettyServer;
import com.doeis.minaserver.container.BasicModule;
import com.doeis.minaserver.dao.User;
import com.doeis.minaserver.dao.UserDao;
import com.doeis.minaserver.module.ClientConnectionManager;
import com.doeis.minaserver.packet.InfoPacket;
import com.doeis.minaserver.packet.ServerPacketFactory;
import com.doeis.minaserver.session.ClientConnection;
import com.doeis.uwork.bean.ComparatorRelation;
import com.doeis.uwork.bean.DoeisItemAssist;
import com.doeis.uwork.common.Constant;
import com.doeis.uwork.dao.GroupMsgMongoDao;
import com.doeis.uwork.dao.ItemDao;
import com.doeis.uwork.dao.PrivateMsgMongo;
import com.doeis.uwork.dao.ShareDao;
import com.doeis.uwork.dao.TemplateDao;
import com.doeis.uwork.entity.Item;
import com.doeis.uwork.entity.Share;
import com.doeis.uwork.entity.Template;
import com.doeis.uwork.entity.mongo.GroupMsg;
import com.doeis.uwork.entity.mongo.PrivateMsg;
import com.doeis.uwork.packet.PrivateMsgPacket;
import com.voland.core.ServiceException;
import com.voland.core.db.DBManager;
import com.voland.core.db.DaoException;
import com.voland.core.db.Page;
import com.voland.core.utils.DateUtils;
import com.voland.core.utils.IDGenerator;

public class PrivateMsgService extends BasicModule {

	private static final Logger log = Logger.getLogger(PrivateMsgService.class);
	
	private UserDao userDao;
	private ItemDao itemDao;
	private ShareDao shareDao;
	private TemplateDao templateDao;
	private PrivateMsgMongo privateMsgMongo;
	private GroupMsgMongoDao groupMsgMongoDao;
	private ClientConnectionManager clientConnectionManager = null ;
	
	
	public PrivateMsgService() {
		super(" private Message Service ");
	}
	
	public PrivateMsgService(String moduleName) {
		super(moduleName);
	}

	@Override
	public void initialize(NettyServer server) {
		this.server = server;
		
		clientConnectionManager = server.getClientConnectionManager();
		userDao = server.getUserDao();
		itemDao = server.getItemDao();
		shareDao = server.getShareDao();
		templateDao = server.getTemplateDao();
		privateMsgMongo = server.getPrivateMsgMongo() ;
		groupMsgMongoDao = server.getGroupMsgMongoDao() ;
		
	}
	
	/**
	 * 添加组外信息
	 * @param clientConn
	 * @param packet
	 */
	public void addMsg(ClientConnection clientConn, PrivateMsgPacket packet) {
		PrivateMsg privateMsg = packet.decoder(PrivateMsg.class);
		try{
			//验证登陆输入的参数
			Map<String, Object> errerInfos = new HashMap<String, Object>();
			if(privateMsg.getFrom()==null){
				errerInfos.put("from", "发送人不能为空");
			}
			if(privateMsg.getTo()==null){
				errerInfos.put("to", "接受人不能为空");
			}
			
			if(privateMsg.getSourceType()==null){
				errerInfos.put("sourceType", "共享信息类型不能为空");
			}
			
			if(privateMsg.getMsceneType()==null){
				errerInfos.put("msceneType", "小场景类型不能为空");
			}
			
			if(privateMsg.getSourceId()==null){
				errerInfos.put("sourceId", "指数、模板、拼图id不能为空");
			}
			
			if(privateMsg.getContent()==null){
				errerInfos.put("content", "聊天信息不能为空");
			}
			if (errerInfos.size() > 0 ) {				
				sendSystemPacket(clientConn, packet.getFrom(),errerInfos.toString(),PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String user_id = privateMsg.getFrom() ;
			User fromuser = userDao.findUserByid(user_id);
			if(fromuser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到发送者",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			
			//如果共享信息类型是指数
			if(Constant.SHARE_TYPE_ITEM.equals(privateMsg.getSourceType())){
				//设置指数的原始ID
				Item item = itemDao.findItemByid(privateMsg.getSourceId());
				if(Constant.DATA_SOURCE_SHARE.equals(item.getData_source())){
					privateMsg.setSourceId(item.getOriginal_item_id());
				}
				privateMsg.setSourceName(item.getItem_name());
			}else if(Constant.SHARE_TYPE_TEMPLATE.equals(privateMsg.getSourceType())){
				Template template = templateDao.findTemplateByid(privateMsg.getSourceId());
				if(template!=null){//TODO
					Share share = shareDao.findShareByid(privateMsg.getShareid());
					privateMsg.setSourceId(share.getSource_id());
					privateMsg.setSourceName(template.getName());
				}
			}
			
			User touser = userDao.findUserByid(privateMsg.getTo());
			if(touser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到接受者",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			privateMsg.setFromName(fromuser.getName());
			privateMsg.setToName(touser.getName());
			privateMsg.setCreated_at(DateUtils.currentDateTime());
			add(privateMsg, fromuser.getSwitchboard_id());
			
			packet.setTo(user_id);
			privateMsg.setHead_pic(fromuser.getHead_pic());
			packet.setBody(JSON.toJSONString(privateMsg));
			
			PrivateMsgPacket reply = ServerPacketFactory.replyAddPrivateMessage(packet);
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			clientConn.deliver(reply);
		}catch(Exception e){
			e.printStackTrace();
			log.error("查询用户", e.getCause());
		}finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}
	
	private PrivateMsg add(PrivateMsg msg, String myswitchbaord) throws ServiceException{
		try{
			Timestamp time = DateUtils.currentDateTime();
			msg.setCreated_at( time );
			
			User to = userDao.findUserByid(msg.getTo());
			if(to==null){
				msg.setError("发送到的用户不存在");
				return msg;
			}
			msg.setId( IDGenerator.uuid());		
			//分别给自己与对方存入这条信息
			privateMsgMongo.insert(myswitchbaord, msg);
			privateMsgMongo.insert(to.getSwitchboard_id(), msg);
			//推送私密聊天信息
			PrivateMsgPacket reply = ServerPacketFactory.createPrivateMessagePacket(to.getId());
			reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_ADD_OTHER);
			msg.setHead_pic(to.getHead_pic());
			reply.setBody(JSON.toJSONString(msg));
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			ClientConnection clientConnection = clientConnectionManager.getAuthConnection(to.getId());
			if(clientConnection!=null){
				clientConnection.deliver(reply);
			}
			return msg;
		}catch(Exception e){
			throw new ServiceException(e);
		}		
	}
	
	/**
	 * 获取列表聊天信息
	 * @param userId 用户ID
	 * @param _start 开始个数
	 * @param _end 结束个数
	 * @param clientConn
	 * @param p
	 */
	public void listMsg(ClientConnection clientConn, PrivateMsgPacket packet) {
		try {
			PrivateMsg privateMsg = packet.decoder(PrivateMsg.class);
			//验证登陆输入的参数
			Map<String, Object> errerInfos = new HashMap<String, Object>();
			if(privateMsg.getFrom()==null){
				errerInfos.put("from", "登陆者不能为空");
			}
			if(privateMsg.getSourceType()==null){
				errerInfos.put("sourceType", "共享信息类型不能为空");
			}
			
			if(privateMsg.getSourceId()==null){
				errerInfos.put("sourceId", "指数、模板、拼图id不能为空");
			}
			if (errerInfos.size() > 0 ) {				
				sendSystemPacket(clientConn, packet.getFrom(),errerInfos.toString(),PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String user_id = privateMsg.getFrom() ;
			User fromuser = userDao.findUserByid(user_id);
			if(fromuser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到发送者",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			//如果共享信息类型是指数
			if(Constant.SHARE_TYPE_ITEM.equals(privateMsg.getSourceType())){
				//设置指数的原始ID
				Item item = itemDao.findItemByid(privateMsg.getSourceId());
				if(item!=null && Constant.DATA_SOURCE_SHARE.equals(item.getData_source())){
					privateMsg.setSourceId(item.getOriginal_item_id());
				}
			}else if(Constant.SHARE_TYPE_TEMPLATE.equals(privateMsg.getSourceType())){
				Template template = templateDao.findTemplateByid(privateMsg.getSourceId());
				if(template!=null){//TODO
					Share share = shareDao.findShareByid(privateMsg.getShareid());
					if(share!=null){
						privateMsg.setSourceId(share.getSource_id());
					}
				}
			}
			Integer start = privateMsg.getPage();
			Integer count = 10;
			if(start==null){
				start = 0;
			}
//			if(reuslt.getPer()==null){
//				reuslt.setPer(10);
//			}
//			reuslt = privateMsgMongo.findPrivateMsg(fromuser.getSwitchboard_id(), reuslt,  privateMsg);
			List<PrivateMsg> msgs = privateMsgMongo.findPrivateMsg(fromuser.getSwitchboard_id(), start,count,  privateMsg);
			
			if(msgs!=null){//处理聊天信息的头像连接
				for( PrivateMsg temp : msgs){
					if( user_id.equals(temp.getFrom()) ){
						temp.setHead_pic(fromuser.getHead_pic());
					}else{
						User user = userDao.findUserByid(temp.getFrom());
						if(user!=null){
							temp.setHead_pic(user.getHead_pic());
						}
					}
				}
			}
			
			packet.setTo(user_id);
			packet.setBody(JSON.toJSONString(msgs));
			PrivateMsgPacket reply = ServerPacketFactory.replyAddPrivateMessage(packet);
			if (packet.getCmd()==PrivateMsgPacket.CMD_MSG_LIST) {
				reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_LIST);
			}else {
				reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_LIST_PMSG);
			}
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			clientConn.deliver(reply);
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}
	/**
	 * 获取群聊天人员列表
	 * @param clientConn
	 * @param packet
	 */
	public void listShareUser(ClientConnection clientConn, PrivateMsgPacket packet) {
		try {
			PrivateMsg privateMsg = packet.decoder(PrivateMsg.class);
			//验证登陆输入的参数
			Map<String, Object> errerInfos = new HashMap<String, Object>();
			if(privateMsg.getFrom()==null){
				errerInfos.put("from", "登陆者不能为空");
			}
			if(privateMsg.getSourceType()==null){
				errerInfos.put("sourceType", "共享信息类型不能为空");
			}
			
			if(privateMsg.getSourceId()==null){
				errerInfos.put("sourceId", "指数、模板、拼图id不能为空");
			}
			if (errerInfos.size() > 0 ) {				
				sendSystemPacket(clientConn, packet.getFrom(),errerInfos.toString(),PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String user_id = privateMsg.getFrom();
			
			User myuser = userDao.findUserByid(user_id);
			if(myuser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到用户",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String share_user_id = privateMsg.getFrom();
			//判断原始指数所有者是否能和组外的人聊天
			 Share shareForm = new Share();
			 shareForm.setScope(Constant.SHARE_SCOPE_ZHIDING_FANGDO);
			 shareForm.setSource_type(privateMsg.getSourceType());
			 shareForm.setUser_id(myuser.getId());
			 shareForm.setSource_id(privateMsg.getSourceId());
			 shareForm = shareDao.findShare(shareForm);
			 List<User> listUser = new ArrayList<User>();
			if(shareForm!=null && shareForm.getEmails()!=null){
				User user = null;
				User temp= null;
				for(String mobile : shareForm.getEmails().split(" ")){
					user = userDao.findUserByLogin(mobile);
					temp = new User();
					temp.setId(user.getId());
					temp.setName(user.getName());
					listUser.add(temp);
				}
			}
			
			packet.setTo(user_id);
			packet.setBody(JSON.toJSONString(listUser));
			PrivateMsgPacket reply = ServerPacketFactory.replyAddPrivateMessage(packet);
			reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_LIST_SHARE_USER);
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			clientConn.deliver(reply);
		} catch (DaoException e) {
			e.printStackTrace();
		} finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}

	/**
	 * 获取群聊天胶片（图片）列表
	 * @param fromConn
	 * @param packet
	 */
	public void listPicture(ClientConnection clientConn, PrivateMsgPacket packet) {
		try {
			PrivateMsg privateMsg = packet.decoder(PrivateMsg.class);
			//验证登陆输入的参数
			Map<String, Object> errerInfos = new HashMap<String, Object>();
			if(privateMsg.getFrom()==null){
				errerInfos.put("from", "登陆者不能为空");
			}
			if(privateMsg.getSourceType()==null){
				errerInfos.put("sourceType", "共享信息类型不能为空");
			}
			
			if(privateMsg.getSourceId()==null){
				errerInfos.put("sourceId", "指数、模板、拼图id不能为空");
			}
			if (errerInfos.size() > 0 ) {				
				sendSystemPacket(clientConn, packet.getFrom(),errerInfos.toString(),PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String user_id = privateMsg.getFrom();
			
			User myuser = userDao.findUserByid(user_id);
			if(myuser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到用户",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			//如果共享信息类型是指数
			if(Constant.SHARE_TYPE_ITEM.equals(privateMsg.getSourceType())){
				//设置指数的原始ID
				Item item = itemDao.findItemByid(privateMsg.getSourceId());
				if(Constant.DATA_SOURCE_SHARE.equals(item.getData_source())){
					privateMsg.setSourceId(item.getOriginal_item_id());
				}
			}else if(Constant.SHARE_TYPE_TEMPLATE.equals(privateMsg.getSourceType())){
				Template template = templateDao.findTemplateByid(privateMsg.getSourceId());
				if(template!=null){//TODO
					Share share = shareDao.findShareByid(privateMsg.getShareid());
					if(share!=null){
						privateMsg.setSourceId(share.getSource_id());
					}
				}
			}
			List<PrivateMsg> reuslt = privateMsgMongo.findPrivateMsgByImg(privateMsg.getSourceId(), myuser.getSwitchboard_id(),  
					privateMsg.getFrom());
			ComparatorRelation comparator=new ComparatorRelation("created_at",Constant.ORDER_DESCENDING);
			Collections.sort(reuslt, comparator);
			packet.setTo(user_id);
			packet.setBody(JSON.toJSONString(reuslt));
			
			PrivateMsgPacket reply = ServerPacketFactory.replyAddPrivateMessage(packet);
			reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_LIST_PICTURE);
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			clientConn.deliver(reply);
		} catch (DaoException e) {
			e.printStackTrace();
		} finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}
	/**
	 * 获取群聊天胶片（图片）列表
	 * @param fromConn
	 * @param packet
	 */
	public void getPrivateGroupMsgCount(ClientConnection clientConn, PrivateMsgPacket packet) {
		try {
			PrivateMsg privateMsg = packet.decoder(PrivateMsg.class);
			//验证登陆输入的参数
			Map<String, Object> errerInfos = new HashMap<String, Object>();
			if(privateMsg.getFrom()==null){
				errerInfos.put("from", "登陆者不能为空");
			}
			if(privateMsg.getSourceType()==null){
				errerInfos.put("sourceType", "共享信息类型不能为空");
			}
			
			if(privateMsg.getSourceId()==null){
				errerInfos.put("sourceId", "指数、模板、拼图id不能为空");
			}
			if (errerInfos.size() > 0 ) {				
				sendSystemPacket(clientConn, packet.getFrom(),errerInfos.toString(),PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			String user_id = privateMsg.getFrom();
			
			User myuser = userDao.findUserByid(user_id);
			if(myuser==null){
				sendSystemPacket(clientConn, packet.getFrom(),"没有找到用户",PrivateMsgPacket.NT_RE_MSG_OK,InfoPacket.NOTIFY_PARAM_NULL);
				return ;
			}
			
			//查找是否有组内聊天
			GroupMsg groupMsg = new GroupMsg();
			groupMsg.setUserId(myuser.getId());
			
			//查找是否有私密聊天
			PrivateMsg privateMsg1 = new PrivateMsg();
			privateMsg1.setFrom(myuser.getId());
			
			if(Constant.SHARE_TYPE_ITEM.equals(privateMsg.getSourceType())){
				Item item = itemDao.findItemByid(privateMsg.getSourceId());
				if(Constant.DATA_SOURCE_SHARE.equals(item)){
					groupMsg.setSourceId(item.getOriginal_item_id());
					privateMsg1.setSourceId(item.getOriginal_item_id());
				}else{
					groupMsg.setSourceId(item.getId());
					privateMsg1.setSourceId(item.getId());
				}
			}
			DoeisItemAssist itemAssist = new DoeisItemAssist();
			Page<GroupMsg> page_msg = groupMsgMongoDao.findGroupMsg(myuser.getSwitchboard_id(), new Page(1, 1), groupMsg);
			if(page_msg.getResults().size()>0){
				itemAssist.setGmsg_show(true);
			}else{
				itemAssist.setGmsg_show(false);
			}
			
			Page<PrivateMsg> private_msg = privateMsgMongo.findPrivateMsg(myuser.getSwitchboard_id(), 
					new Page(1, 1), privateMsg1);
			if(private_msg.getResults().size()>0){
				itemAssist.setPmsg_show(true);
			}else{
				itemAssist.setPmsg_show(false);
			}
			packet.setTo(user_id);
			packet.setBody(JSON.toJSONString(itemAssist));
			PrivateMsgPacket reply = ServerPacketFactory.replyAddPrivateMessage(packet);
			reply.setCmd(PrivateMsgPacket.NOTIFY_MSG_GET_MSG_COUNT);
			reply.setNotifyType(PrivateMsgPacket.NT_RE_MSG_OK);
			clientConn.deliver(reply);
		} catch (DaoException e) {
			e.printStackTrace();
		} finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}
}
